﻿#ifndef PST_HEATMAPWINDOW_H
#define PST_HEATMAPWINDOW_H

#include "Graph2DWindowBase.h"

#include "DataModelPost.h"
#include "InfomationCurve2DBasical.h"
#include <opencv2/opencv.hpp>

class QStandardItem;

namespace pst
{
    class TwoDHeatMapSettings;
    class DataHeatGraph2DSettings;
    class LineChartTracer;
    class TracerTableWidget;
    class AnimationSettingData;
    class AnimationTooBarInfoData;
    /// @brief 二维图形
    class HeatMapWindow : public Graph2DWindowBase
    {
        Q_OBJECT
    public:
        explicit HeatMapWindow(QWidget* parent, int windowId);
        ~HeatMapWindow();

        /// @brief 文件写出至工程文件
        QDomElement& writeToProjectFile(QDomDocument* doc, QDomElement* element, bool isdiso = false) override;

        /// @brief 从工程文件读入数据
        void readFromProjectFile(QDomElement* element, bool isdiso = false) override;

        void setWindowID(int windowID) override;
        int getWindowID() const override;

        void setWindowUniversalID(int windowUniversalID) override;
        int getWindowUniversalID() const override;

        DataHeatGraph2DSettings* getDataHeatGraph2DSettings() { return m_dataHeatGraph2DSettings; };

        void addGraph2D(Info2DPointer& info) override; // 传引用，改数据

        bool GetColorScaleFlag() const
        {
            return m_autoColorScale;
        }
        void SetColorScaleFlag(bool autoColorScale)
        {
            m_autoColorScale = autoColorScale;
        }
        bool GetXAutoFlag() const
        {
            return m_autoXRescaleAxes;
        }
        void SetXAutoFlag(bool autoXRescaleAxes)
        {
            m_autoXRescaleAxes = autoXRescaleAxes;
        }
        bool GetYAutoFlag() const
        {
            return m_autoYRescaleAxes;
        }
        void SetYAutoFlag(bool autoYRescaleAxes)
        {
            m_autoYRescaleAxes = autoYRescaleAxes;
        }

        void setActiveAnimation(bool active);

        void exportAnimationData(const QString& path);

        void setAnimationSettingData(AnimationSettingData* data);
        AnimationSettingData* getAnimationSettingData() const;

        void setAnimationType(int type);
        int getAnimationType() const;

        void increaseAnimationSpeed();
        void decreaseAnimationSpeed();
        double getSpeedFactor() const;

        bool GetXTitleAutoFlag() const
        {
            return m_autoXTitleText;
        }
        void SetXTitleAutoFlag(bool autoXTitleText)
        {
            m_autoXTitleText = autoXTitleText;
        }
        bool GetYTitleAutoFlag() const
        {
            return m_autoYTitleText;
        }
        void SetYTitleAutoFlag(bool autoYTitleText)
        {
            m_autoYTitleText = autoYTitleText;
        }

        // 根据数据判断是否可以启用动图
        bool whetherCanEnableDataAnimation();

        bool isInfoContainsMultipleData(const Info2DPointer& info);

    public: // 给脚本调用
        void setSelectedCurveNameIndexs(QList<int> selectedCurveNameIndexs);
        void setVariableAxisChanged(int variableAxisIndex);
        void setSecondVariableAxisChanged(int variableAxisIndex);
        void setCurveNameCheckStateChanged(int curveNameIndex, bool checkState);
        void setDataOprationChanged(bool isLoged, bool isNormalized);
        void setResultValueDataChanged(int valueIndex);
        void saveHeatMapMainSettingData(bool scalarBarIsAutoRange, double scalarBarMin, double scalarBarMax,
                                        QString scalarBarColor, int scalarBarFontSize, bool XAxisAutoTitle, QString XAxisTitle, QString XTitleFontColor, int XTitleFontSize,
                                        QString XAxisColor, double XAisThickness, int XValuePrecision, QString XAxisDigitColor, int XAxisDigitSize,
                                        bool XAxisIsAutoRange, double XAxisMax, double XAxisMin, bool XIsAutoStepSize, double XCustomStepSize,
                                        bool YAxisAutoTitle, QString YAxisTitle, QString YTitleFontColor, int YTitleFontSize,
                                        QString YAxisColor, double YAisThickness, int YValuePrecision, QString YAxisDigitColor, int YAxisDigitSize,
                                        bool YAxisIsAutoRange, double YAxisMax, double YAxisMin, bool YIsAutoStepSize, double YCustomStepSize,
                                        bool gridIsMainGridLineDisplay, QString gridMainGridLineColor, int gridMainGridLineStyle, double gridMainGridLineThickness,
                                        bool gridIsSecondaryGridLineDisplay, QString gridSecondaryGridLineColor, int gridSecondaryGridLineStyle, double gridSecondaryGridLineThickness,
                                        QString windowTitleName, QString windowTitleFontColor, int windowTitleFontSize);
        void setFixedValueChanged(QList<int> indexList);
        void setComplexPartsChanged(bool isAmplitudeChecked, bool isPhaseChecked, bool isRealPartChecked, bool isImaginaryPartChecked);
        void setRemoveSelectedGraph();
        void setRenameFinished(QString name);

        void changeHeatMapProperty(const DataHeatGraph2DSettings* dataGraph2DSettings);

        void setAnimationTooBarInfoData(AnimationTooBarInfoData* info);
        AnimationTooBarInfoData* getAnimationTooBarInfoData();

        void setFrameToBeforeExportAnimation();
        void sentToolBarAnimationDataInfo(const Info2DPointer& info);
        void deleteGraphs(const QList<Info2DPointer>& infos );

    public slots:
        void slot_adaptiveRange() override;
        void slot_chosenItemsChanged(const QModelIndexList& itemList); // override;
        void slot_generateANewGraphCurve(const QModelIndexList& itemList,
                                         const Info2DPointer& changedInfo);

        void slot_HeatMapPropertyShow(QCPColorMap* plottable, int index);
        void slot_ChangeHeatMapProperty(int windowUniversalID, int curveInfoID, Info2DPointer info = nullptr);
        void slot_showHideItemActor(QStandardItem* item);

        void slot_AddTracer();
        void slot_ShowPreviewTracer(QMouseEvent* event);
        void slot_removeSelectedTracer(const QList<LineChartTracer*>& selectTracers);
        void slot_removeAllTracer(const QList<LineChartTracer*>& tracers);
        void slot_TracerPropertyShow(LineChartTracer* tracer);
        void slot_ChangeTracerProperty(int tracerID, int guideLineID);
        void slot_updateHeatmapTracerProperty();
        void slot_beginToPlayDataAnimation();
        void slot_getSidebarCurveDataSource(QStandardItem* item, QString& dataSource);

        void slot_autoGetXTitleText(QString& xTitleText);
        void slot_autoGetYTitleText(QString& yTitleText);

        //左侧关闭工程树，删除相应的图像
        // 注意items是左侧工程树的节点
        void slot_closeTree(const QList<QStandardItem*>& items);

        void slot_removeSelectedGraph();
        void slot_removeGraphs(const QList<QString>& graphNameList);
        void slot_renameGraph();
        void slot_renameFinished(QString name);
        void slot_updateSelectedGraph();
        void syncSelectedGraph();

        void slot_exportMarkerData();

    public:
        void pyAddTracer(QString name, double x, double y, double value, int tracerStyle, int size, int penR, int penG, int penB, int penA, int interpolating, int curveInfoID, int tracerIndex);
        void pyRemoveSelectedTracer(QList<int> selectTracersInfoID);
        void pyRemoveAllTracer(QList<int> selectTracersInfoID);
        void pyExportMarkerData(QString fileName);
        void pyChangeTracerProperty(QString name, int symbolStyle, int size, int penR, int penG, int penB, int penA, int tracerID);

    protected:
        void initConnections() override;
        void updateCurve(QStandardItem* item, Info2DPointer& info) override;
        bool eventFilter(QObject* watched, QEvent* event) override;

    private:
        void SetHeatMapData(QVector<double> column1, QVector<double> column2, QVector<double> column3, QCPColorMap* colorMap);
        void prepareAnimationData(); // 准备动画数据
        void updateControlPanel();
        void animationToNextDataFrame();
        void exportAnimationToLocal();
        QString generateGraphNameAuto(const Info2DPointer& info, bool isLog) const;

        /// @brief 二维图形设置
        TwoDHeatMapSettings* m_settings{nullptr};

        bool m_autoColorScale = true;
        bool m_autoXRescaleAxes = true;
        bool m_autoYRescaleAxes = true;
        QCPRange m_xAxisRange;
        QCPRange m_yAxisRange;
        QCPAbstractPlottable* m_doubleClickPlottable = nullptr;
        int m_tracerIndex = 0;
        LineChartTracer* m_doubleClickTracer = nullptr;
        TracerTableWidget* m_tracerPropertyWidget = nullptr;

        //========动画相关设置========//
        int m_animationType;     // 动画类型 0:数据变化 1:相机变化
        double m_animationSpeed; // 动画速度
        AnimationSettingData* m_animationSettingData;
        // QList<InfomationCurve2DBasical> m_graphInfoList;
        // QVector<std::array<QVector<double>, 3>> m_animationData; //动画数据
        QTimer* m_dataTimer;
        bool m_isExportingAnimation;
        int m_loopCount;
        int m_imageSize; // 所有图像的最大帧数
        QList<cv::Mat> m_animationImageList;
        QString m_exportAnimationPath;
        int m_windowId;
        int m_windowUniversalID{-1};

        bool m_autoXTitleText = true;
        bool m_autoYTitleText = true;
        QString m_xUnit;
        QString m_yUnit;

        AnimationTooBarInfoData* m_animationTooBarInfoData;
        bool m_isBeginExportAnimation{false};  // 是否是开始导出动图
        bool m_isFirstTimeDataAnimation{true}; // 是否是第一次数据动画
        int m_animationDataCount{0};           // 本次启动动图后数据的变化次数

        DataHeatGraph2DSettings* m_dataHeatGraph2DSettings;

        bool m_isCurveRenamed{false};
        bool m_isTitleRenamed{ false };

        QHash<int, QString> getMarkerNameMap();

        bool m_isAnimationState{ false };
        // QHash<QStandardItem*, std::array<QVector<double>, 3>> m_animationData;//动画数据
    };
} // namespace pst

#endif // PST_HEATMAPWINDOW_H
